package link.chengguo.orangemall.service.pms.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import link.chengguo.orangemall.ApiContext;
import link.chengguo.orangemall.modules.pms.dto.ProductDetailedDto;
import link.chengguo.orangemall.modules.pms.dto.ProductDto;
import link.chengguo.orangemall.service.cms.ICmsPrefrenceAreaProductRelationService;
import link.chengguo.orangemall.service.cms.ICmsSubjectProductRelationService;
import link.chengguo.orangemall.pms.entity.*;
import link.chengguo.orangemall.pms.mapper.*;
import link.chengguo.orangemall.pms.vo.PmsProductParam;
import link.chengguo.orangemall.pms.vo.PmsProductResult;
import link.chengguo.orangemall.service.pms.*;
import link.chengguo.orangemall.service.ums.RedisService;
import link.chengguo.orangemall.util.DateUtils;
import link.chengguo.orangemall.util.JsonUtil;
import link.chengguo.orangemall.util.UserUtils;
import link.chengguo.orangemall.utils.IdWorker;
import link.chengguo.orangemall.utils.ValidatorUtils;
import link.chengguo.orangemall.vo.Rediskey;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 商品信息 服务实现类
 * </p>
 *
 * @author chengguo
 * @since 2019-04-19
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class PmsProductServiceImpl extends ServiceImpl<PmsProductMapper, PmsProduct> implements IPmsProductService {

    private final PmsProductLadderMapper productLadderMapper;
    private final PmsProductMapper productMapper;
    private final PmsProductFullReductionMapper productFullReductionMapper;
    private final PmsSkuStockMapper skuStockMapper;
    private final PmsProductAttributeValueMapper productAttributeValueMapper;
    private final CmsSubjectProductRelationMapper subjectProductRelationMapper;
    private final CmsPrefrenceAreaProductRelationMapper prefrenceAreaProductRelationMapper;
    private final PmsProductVertifyRecordMapper productVertifyRecordMapper;

    private final RedisService redisService;
    private final IPmsProductAttributeValueService productAttributeValueDao;
    private final ICmsSubjectProductRelationService subjectProductRelationDao;
    private final ICmsPrefrenceAreaProductRelationService prefrenceAreaProductRelationDao;
    private final IPmsSkuStockService skuStockDao;
    private final IPmsProductFullReductionService productFullReductionDao;
    private final IPmsProductLadderService productLadderDao;

    @Override
    public int create(ProductDetailedDto productParam) {
        int count;
        //创建商品
        PmsProduct product = productParam;
        product.setCreateTime(new Date());
        product.setId(null);
        //处理sku的编码
        handleSkuStockCode(productParam.getSkuStockList(), product);
        if (ValidatorUtils.isEmpty(product.getProductSn())) {
            product.setProductSn(IdWorker.getId() + "");
        }
        if (ValidatorUtils.empty(product.getExpireTime())) {
            product.setExpireTime(DateUtils.strToDate(DateUtils.addDay(new Date(), 5)));
        }
        if (ValidatorUtils.empty(product.getOriginalPrice())) {
            product.setOriginalPrice(product.getPrice());
        }
        productMapper.insert(product);
        //根据促销类型设置价格：、阶梯价格、满减价格
        Long productId = product.getId();
        //会员价格
        //   relateAndInsertList(memberPriceDao, productParam.getMemberPriceList(), productId);
        //阶梯价格
        relateAndInsertList(productLadderDao, productParam.getProductLadderList(), productId);
        //满减价格
        relateAndInsertList(productFullReductionDao, productParam.getProductFullReductionList(), productId);

        //添加sku库存信息
        relateAndInsertList(skuStockDao, productParam.getSkuStockList(), productId);
        //添加商品参数,添加自定义商品规格
        relateAndInsertList(productAttributeValueDao, productParam.getProductAttributeValueList(), productId);
        //关联专题
        relateAndInsertList(subjectProductRelationDao, productParam.getSubjectProductRelationList(), productId);
        //关联优选
        relateAndInsertList(prefrenceAreaProductRelationDao, productParam.getPrefrenceAreaProductRelationList(), productId);
        count = 1;
        //    redisService.set(String.format(Rediskey.GOODSDETAIL, product.getId()), JsonUtil.objectToJson(productParam));
        return count;
    }

    private void handleSkuStockCode(List<PmsSkuStock> skuStockList, PmsProduct product) {
        if (CollectionUtils.isEmpty(skuStockList)) {
            return;
        }
        int stock = 0;
        for (int i = 0; i < skuStockList.size(); i++) {
            PmsSkuStock skuStock = skuStockList.get(i);
            skuStock.setProductName(product.getName());
            if (StringUtils.isEmpty(skuStock.getSkuCode())) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
                StringBuilder sb = new StringBuilder();
                //日期
                sb.append(sdf.format(new Date()));
                //四位商品id
                sb.append(String.format("%04d", product.getProductCategoryId()));
                //三位索引id
                sb.append(String.format("%03d", i + 1));
                skuStock.setSkuCode(sb.toString());
            }
            stock = stock + skuStock.getStock();
        }
        product.setStock(stock);
    }

    @Override
    public PmsProductResult getUpdateInfo(Long id) {
        return productMapper.getUpdateInfo(id);
    }

    @Override
    public int update(Long id, ProductDetailedDto productParam) {

        int count;
        //更新商品信息
        PmsProduct product = productParam;
        product.setId(id);
        if (ValidatorUtils.isEmpty(product.getProductSn())) {
            product.setProductSn(IdWorker.getId() + "");
        }
        handleSkuStockCode(productParam.getSkuStockList(), product);
        productMapper.updateById(product);
        redisService.remove(String.format(Rediskey.GOODSDETAIL, product.getId()));
        //会员价格
        //  memberPriceMapper.delete(new QueryWrapper<>(new PmsMemberPrice()).eq("product_id", id));
        //  relateAndInsertList(memberPriceDao, productParam.getMemberPriceList(), id);
        //阶梯价格

        productLadderMapper.delete(new QueryWrapper<>(new PmsProductLadder()).eq("product_id", id));
        relateAndInsertList(productLadderDao, productParam.getProductLadderList(), id);
        //满减价格

        productFullReductionMapper.delete(new QueryWrapper<>(new PmsProductFullReduction()).eq("product_id", id));
        relateAndInsertList(productFullReductionDao, productParam.getProductFullReductionList(), id);
        //修改sku库存信息
        skuStockMapper.delete(new QueryWrapper<>(new PmsSkuStock()).eq("product_id", id));

        relateAndInsertList(skuStockDao, productParam.getSkuStockList(), id);
        //修改商品参数,添加自定义商品规格

        productAttributeValueMapper.delete(new QueryWrapper<>(new PmsProductAttributeValue()).eq("product_id", id));
        relateAndInsertList(productAttributeValueDao, productParam.getProductAttributeValueList(), id);
        //关联专题

        subjectProductRelationMapper.delete(new QueryWrapper<>(new CmsSubjectProductRelation()).eq("product_id", id));
        relateAndInsertList(subjectProductRelationDao, productParam.getSubjectProductRelationList(), id);
        //关联优选

        prefrenceAreaProductRelationMapper.delete(new QueryWrapper<>(new CmsPrefrenceAreaProductRelation()).eq("product_id", id));
        relateAndInsertList(prefrenceAreaProductRelationDao, productParam.getPrefrenceAreaProductRelationList(), id);
        count = 1;

        redisService.set(String.format(Rediskey.GOODSDETAIL, product.getId()), JsonUtil.objectToJson(productParam));
        return count;
    }


    @Override
    public int updateVerifyStatus(Long ids, Integer verifyStatus, String detail) {
        PmsProduct product = new PmsProduct();
        product.setVerifyStatus(verifyStatus);
        int count = productMapper.update(product, new QueryWrapper<PmsProduct>().eq("id", ids));
        //修改完审核状态后插入审核记录

        PmsProductVertifyRecord record = new PmsProductVertifyRecord();
        record.setProductId(ids);
        record.setCreateTime(new Date());
        record.setDetail(detail);
        record.setStatus(verifyStatus);
        record.setVertifyMan(UserUtils.getCurrentMember().getUsername());
        productVertifyRecordMapper.insert(record);
        redisService.remove(String.format(Rediskey.GOODSDETAIL, product.getId()));
        return count;
    }

    @Override
    public int updatePublishStatus(List<Long> ids, Integer publishStatus) {
        PmsProduct record = new PmsProduct();
        record.setPublishStatus(publishStatus);
        clerGoodsRedis(ids);
        return productMapper.update(record, new QueryWrapper<PmsProduct>().in("id", ids));
    }

    public void clerGoodsRedis(List<Long> ids) {
        for (Long id : ids) {
            redisService.remove(String.format(Rediskey.GOODSDETAIL, id));
        }
    }

    @Override
    public int updateRecommendStatus(List<Long> ids, Integer recommendStatus) {
        PmsProduct record = new PmsProduct();
        record.setRecommandStatus(recommendStatus);
        clerGoodsRedis(ids);
        return productMapper.update(record, new QueryWrapper<PmsProduct>().in("id", ids));
    }

    @Override
    public int updateNewStatus(List<Long> ids, Integer newStatus) {
        PmsProduct record = new PmsProduct();
        record.setNewStatus(newStatus);
        clerGoodsRedis(ids);
        return productMapper.update(record, new QueryWrapper<PmsProduct>().in("id", ids));
    }

    @Override
    public int updateDeleteStatus(List<Long> ids, Integer deleteStatus) {
        PmsProduct record = new PmsProduct();
        record.setDeleteStatus(deleteStatus);
        clerGoodsRedis(ids);
        return productMapper.update(record, new QueryWrapper<PmsProduct>().in("id", ids));
    }

    @Override
    public List<PmsProduct> list(String keyword) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("delete_status", 0);
        queryWrapper.eq("shop_id",UserUtils.getCurrentMember().getShopId());

        if (!StringUtils.isEmpty(keyword)) {
            queryWrapper.like("name", keyword);

        }
        queryWrapper.orderByAsc("sort");
        return productMapper.selectList(queryWrapper);
    }

    @Override
    public List<PmsProductVertifyRecord> getProductVertifyRecord(Long id) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("product_id", id);

        return productVertifyRecordMapper.selectList(queryWrapper);
    }

    @Override
    public IPage<PmsProduct> pageByName(Integer pageNum,Integer pageSize,  String keyword) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("delete_status", 0);
        queryWrapper.eq("shop_id",UserUtils.getCurrentMember().getShopId());
        if (!StringUtils.isEmpty(keyword)) {
            queryWrapper.like("name",keyword);

        }
        queryWrapper.orderByAsc("create_time");
        return this.page(new Page<>(pageNum,pageSize),queryWrapper);
    }


    /**
     * 建立和插入关系表操作
     *
     * @param dao       可以操作的dao
     * @param dataList  要插入的数据
     * @param productId 建立关系的id
     */
    private void relateAndInsertList(Object dao, List dataList, Long productId) {
        try {
            if (CollectionUtils.isEmpty(dataList)) {
                return;
            }
            for (Object item : dataList) {
                Method setId = item.getClass().getMethod("setId", Long.class);
                setId.invoke(item, (Long) null);
                Method setProductId = item.getClass().getMethod("setProductId", Long.class);
                setProductId.invoke(item, productId);
                Method setCityCode = item.getClass().getMethod("setCityCode", String.class);
                setCityCode.invoke(item, UserUtils.getCurrentMember().getCityCode());
            }
            Method insertList = dao.getClass().getMethod("saveBatch", Collection.class);
            insertList.invoke(dao, dataList);
        } catch (Exception e) {

            log.warn("创建产品出错:{}", e.getMessage());
            throw new RuntimeException(e.getMessage());
        }
    }

}


